#include <iostream>
#include <memory>
#include "Route.hpp"      //路由服务的功能
#include "UdpServer.hpp"  //网络通信的功能
#include "ThreadPool.hpp" //线程池轮流处理任务功能

using namespace ThreadPoolModule;

using task_t = function<void()>;

// ./udpserver port
int main(int argc, char *argv[])
{
    // 判断命令行参数是否传了上面的三个
    if (argc != 2)
    {
        std::cerr << "Usage: " << argv[0] << " port" << std::endl;
        return 1;
    }

    uint16_t port = std::stoi(argv[1]);
    Enable_Console_Log_Strategy();

    // 1.路由服务——Route.hpp
    Route r;

    // 2.线程池-ThreadPool.hpp
    auto tp = ThreadPool<task_t>::GetInstance();

    // 3.网络服务器对象提供通信功能-UdpServer.hpp
    std::unique_ptr<UdpServer> usvr = std::make_unique<UdpServer>(port, [&r, &tp](int sockfd, const std::string &message, InetAddr &peer)
                                                                  {
        //这里我们可以采用std中的bind参数绑定函数
        //意思就是把sockfd、message、peer三个参数传入r对象的MessageRoute函数中
        //然后我们调用t时就会调用MessageRoute函数，并传入这三个参数
        //（在函数取地址作为参数后的是可变参数列表，可以传不限制的参数）
        //其次绑定成员函数时需要传入对象指针作为第一个参数，上面三个参数紧接其后
        //若需显式类型，可使用 std::function 包装 -> 上面的task_t
        task_t t=std::bind(&Route::MessageRoute,&r,sockfd,message,peer); 
        //将这个bind好的任务t入任务队列中去，让线程们来轮流执行
        tp->Enqueue(t); });

    // std::unique_ptr<UdpServer> usvr = std::make_unique<UdpServer>(port, [&r](int sockfd, const std::string &message, InetAddr &peer)
    //                                                               { r.MessageRoute(sockfd, message, peer); }); // c++14
    usvr->Init();
    usvr->Start();

    return 0;
}